#!/usr/bin/python3
# -*- coding: utf-8 -*-

"""
# @version: v1.0
# @author : cd
# @Email : 19688513@qq.com
# @Project : new-horizons-engine
# @File : PathManager.py
# @Software: PyCharm
# @time: 2025/5/30 9:43
# @description : 路径管理帮助类，用于创建和管理标准化目录结构
"""

import urllib3

import os
import sys
from typing import Optional

# 禁用不安全的请求警告
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)


class PathManager:
    """
    路径管理帮助类，用于创建和管理标准化目录结构

    功能：
    1. 自动获取运行目录
    2. 创建标准化子目录
    3. 提供标准化路径访问
    4. 支持跨平台路径处理
    """

    def __init__(self, base_dir: Optional[str] = None):
        """
        初始化路径管理器

        :param base_dir: 可选的基础目录，默认使用当前文件所在目录
        """
        self._verify_system_compatibility()

        # 基础目录设置
        if base_dir:
            self.base_dir = os.path.abspath(base_dir)
        else:
            self.base_dir = self._get_running_path()

        # 标准子目录配置
        self.dir_config = {
            'data': 'data',
            'database': 'data/db',
        }

        # 自动创建必要目录
        self.create_required_directories()

    @staticmethod
    def _verify_system_compatibility():
        """验证系统兼容性"""
        if sys.platform not in ['win32', 'darwin', 'linux']:
            raise OSError("Unsupported operating system")

    def _get_running_path(self) -> str:
        """
        获取当前运行的文件所在目录（兼容各种执行方式）

        兼容以下场景：
        - 直接运行的脚本
        - 打包后的可执行文件
        - 作为模块导入的情况
        """
        if getattr(sys, 'frozen', False):
            # 打包后的可执行文件
            return os.path.dirname(sys.executable)
        elif '__file__' in globals():
            # 直接运行的脚本
            return os.path.dirname(os.path.abspath(__file__))
        else:
            # 交互式环境或其他情况
            return os.getcwd()

    def create_required_directories(self):
        """创建所有必要的目录"""
        required_dirs = [
            self.database_dir,
            self.get_path('data')  # 创建数据目录
        ]

        for directory in required_dirs:
            self.safe_create_dir(directory)

    def safe_create_dir(self, path: str) -> str:
        """
        安全创建目录（如果不存在）

        :param path: 要创建的目录路径
        :return: 实际创建的路径
        """
        try:
            os.makedirs(path, exist_ok=True)
            self._set_dir_permissions(path)
            return path
        except OSError as e:
            raise RuntimeError(f"Failed to create directory {path}: {str(e)}")

    @staticmethod
    def _set_dir_permissions(path: str):
        """设置目录权限（跨平台兼容）"""
        if sys.platform != 'win32':
            # 在Linux/macOS设置755权限
            os.chmod(path, 0o755)

    @property
    def database_dir(self) -> str:
        """获取数据库目录路径"""
        return self.get_path('database')

    @property
    def logs_dir(self) -> str:
        """获取日志目录路径"""
        return self.get_path('logs')

    @property
    def config_dir(self) -> str:
        """获取配置目录路径"""
        return self.get_path('config')

    def get_path(self, dir_type: str, *subpaths) -> str:
        """
        获取标准化路径

        :param dir_type: 目录类型 (data/database/logs/config)
        :param subpaths: 附加的子路径
        :return: 完整的标准化路径
        """
        if dir_type not in self.dir_config:
            raise ValueError(f"Invalid directory type: {dir_type}")

        base_path = os.path.join(
            self.base_dir,
            self.dir_config[dir_type]
        )

        full_path = os.path.join(base_path, *subpaths)
        return os.path.normpath(full_path)

    def get_database_path(self, db_name: str) -> str:
        """
        获取数据库文件的完整路径

        :param db_name: 数据库文件名（含扩展名）
        :return: 完整的数据库文件路径
        """
        if not db_name.endswith('.db'):
            db_name += '.db'
        return self.get_path('database', db_name)


# 示例用法
if __name__ == '__main__':
    # 初始化路径管理器
    pm = PathManager()

    # 打印关键路径
    print(f"运行目录: {pm.base_dir}")
    print(f"数据库目录: {pm.database_dir}")
    print(f"示例数据库路径: {pm.get_database_path('test.db')}")

    # 创建新目录示例
    custom_dir = pm.get_path('data', 'custom')
    pm.safe_create_dir(custom_dir)
    print(f"自定义目录已创建: {custom_dir}")
